#include "Book_t.h"
#include "Borrower_t.h"

Book_t::Book_t(const std::string& bookName, const std::string& author, ull bookISBN, size_t copies)
	: m_bookName(bookName)
	, m_bookAuthor(author)
	, m_ISBN(bookISBN)
	, m_numCopies(copies)
	, m_numAvailCopies(copies)
{

}


Book_t::~Book_t()
{

}

void Book_t::addBorrower(Borrower_t* const borrower)
{
	// check if he is not on the borrowing lists
	if(alreadyBorrowed(borrower,1))
		// we should never enter here because we've checked that on the borrower
		return;

	m_borrowers.push_back(borrower);
	m_numAvailCopies--;
}

void Book_t::addWaitingBorrower(Borrower_t* const borrower)
{
	// check if he is not already on the list
	if(alreadyBorrowed(borrower,2))
		return;

	m_waitingBorrowers.push_back(borrower);
}

bool Book_t::alreadyBorrowed(Borrower_t* const borrower, int listType) const
{
	// listType = 1: borrowers list. 2: waiting lis
	borrowersList::const_iterator it = (listType==1)? m_borrowers.begin() : m_waitingBorrowers.begin();
	borrowersList::const_iterator itEnd = (listType==1)? m_borrowers.end() : m_waitingBorrowers.end();
	while(it != itEnd)
	{
		if(borrower == *it)
			return true;
		it++;
	}

	return false;
}

bool Book_t::operator==(const Book_t* other) const
{
	return m_ISBN == other->m_ISBN;
}

void Book_t::returnBook(Borrower_t* borrower)
{
	// check if borrower actually borrowed the book
	if(!alreadyBorrowed(borrower,1))
		return;

	m_borrowers.remove(borrower);	
	m_numAvailCopies++;
}

Borrower_t* Book_t::whoWaits()
{
	Borrower_t* waitingBorrower = m_waitingBorrowers.front();
	m_waitingBorrowers.remove(waitingBorrower);
	return waitingBorrower;
}


std::ostream& operator<<(std::ostream& os, const Book_t& book)
{
	os << "\""<< book.m_bookName <<"\" by " << book.m_bookAuthor << std::endl ;
	os.fill('-');
	os.width(book.m_bookName.length()+book.m_bookAuthor.length()+6);
	os << "-";
	os << std::endl;
	os << "Status: " << (book.isAvailable()? "AVAILABLE" : "OUT") << std::endl;
	os << "ISBN: " << book.m_ISBN << std::endl;
	os << "Available/Total Copies: " << book.m_numAvailCopies << "/" <<book.m_numCopies << std::endl;
	//os << "Available Copies: " << book.m_numAvailCopies << std::endl;
	os << "Borrowed By: ";
	if(book.m_borrowers.empty())
		os << "no one " << std::endl;
	else
	{
		int i=1;
		os << std::endl;
		Book_t::borrowersList::const_iterator it = book.m_borrowers.begin();
		while(it != book.m_borrowers.end())
		{
			os << "\t" << i << ". " << *(*it) << std::endl;
			i++;
			it++;
		}
	}
	os << "Borrowes on waiting list: ";
	if(!book.isSomeoneWaiting())
		os << "no one " << std::endl;
	else
	{
		int i=1;
		os << std::endl;
		Book_t::borrowersList::const_iterator it = book.m_waitingBorrowers.begin();
		while(it != book.m_waitingBorrowers.end())
		{
			os << "\t" << i << ". " << *(*it) << std::endl;
			i++;
			it++;
		}
	}

	os  << std::endl;

	return os;
}